﻿using Avalonia.Animation;
using LightCAD.Core;
using LightCAD.Core.Element3d;
using LightCAD.Drawing.Actions;
using LightCAD.MathLib;
using LightCAD.Model;
using LightCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LightCAD.Component.Actions
{
    public class CuboidAction : ComponentInstance2dAction
    {
        public CuboidAction() : base()
        {

        }

        public CuboidAction (IDocumentEditor docEditor) : base(docEditor)
        {
            this.commandCtrl.WriteInfo("命令：Cuboid");
        }

        public async void ExecCreate(string[] args = null)
        {
            //var cube = new LcCubeInstance(200, ComponentManager.GetCptDef<LcCubeDef>("立方体", "立方体", CubeAttribute.BuiltinUuid));
            //cube.Initilize(this.docRt.Document);
            //cube.Position.Set(-100, -100, -100);
            //this.docRt.Document.ModelSpace.InsertElement(cube);
        }
    }

    public class Cuboid3dAction : ComponentInstance3dAction
    {
        private LcCuboidInstance cuboid = null;
        public Cuboid3dAction(IDocumentEditor docEditor) : base(docEditor)
        {
            this.commandCtrl.WriteInfo("命令：Cuboid");
        }
        public Cuboid3dAction() : base()
        {

        }
        public async void ExecCreate(string[] args = null)
        {
            Vector3 startP = null;
            Vector3 endP = null;
            PointInputer3d pointer = new PointInputer3d(docEditor);
            FaceInputerResult pr = null;
            PlanarSurface3d plane = null;
            LcCuboidInstance solidEle = null;
            double pullDist = 0;
            bool startPush = false;
            StartAction();
            this.model3dRuntime.EnableCameraControl(false);
            this.snap3dRuntime.AddSnapPlanes(new ListEx<Plane>
            {
                new Plane().SetFromNormalAndCoplanarPoint(new Vector3(0, 0, 1), new Vector3())
            });
            void onMouseEvent(string name, MouseEventRuntime mer)
            {
                if (name == "Move")
                {
                    if (!startPush)
                    {
                        if (startP == null)
                        {
                            return;
                        }

                        endP = this.snap3dRuntime.SnapPoint;
                        if (endP != null)
                        {
                            this.CreateOrUpdateCuboid(startP, endP, 1);
                        }
                    }
                    else
                    {
                        if (solidEle != null && pr != null)
                        {
                            Move(this.snap3dRuntime.SnapPoint);
                        }
                    }
                }
                else if (name == "Down")
                {
                    if (startP == null)
                    {
                        startP = this.snap3dRuntime.SnapPoint.Clone();
                    }
                    else if (!startPush)
                    {
                        startPush = true;
                        //var topFace = this.cuboid.Solid.TopoFaceModel.Surfaces[4];
                        pr = new FaceInputerResult()
                        {
                            //Surface = topFace,
                            Element = this.cuboid,
                            SnapPoint = this.snap3dRuntime.SnapPoint.Clone()
                        };

                        //plane = pr.Surface as PlanarSurface3d;
                        //var nor = plane.Normal;
                        var nor = new Vector3(0, 0, 1);
                        solidEle = pr.Element as LcCuboidInstance;
                        this.snap3dRuntime.ClearSnapPlanes();
                        var camera = this.snap3dRuntime.GetCamera();
                        var yAxis = camera.getWorldDirection().Negate().Cross(nor).Normalize();
                        var zAxis = nor.Clone().Cross(yAxis).Normalize();
                        this.snap3dRuntime.AddSnapPlanes(new ListEx<Plane>
                        {
                            new Plane().SetFromNormalAndCoplanarPoint(zAxis,pr.SnapPoint)
                        });
                    }
                    else if (startPush)
                    {
                        this.snap3dRuntime.EndSnaping();
                        this.model3dRuntime.Control.DetachEvents(null, null, onMouseEvent, null, null, null, null);
                        this.snap3dRuntime.ClearSnapPlanes();
                        this.model3dRuntime.EnableCameraControl(true);
                    }
                }
            }

            void Move(Vector3 target)
            {
                //var nor = plane.Normal;
                var nor = new Vector3(0, 0, 1);
                var pullTotal = (target - pr.SnapPoint).Dot(nor);
                var offset = pullTotal - pullDist;
                pullDist = pullTotal;
                //solidEle.PushOrPullFace(plane, offset);
                CreateOrUpdateCuboid(startP, endP, pullDist);
            }
            this.snap3dRuntime.StartSnaping(SnapFilterType.OnlyPlane);
            this.model3dRuntime.Control.AttachEvents(null, null, onMouseEvent, null, null, null, null);
        end:
            EndAction();
        }

        public void CreateOrUpdateCuboid(Vector3 start, Vector3 end, double depth)
        {
            if (this.cuboid != null)
            {
                this.docRt.Document.ModelSpace.RemoveElement(this.cuboid);
            }
            var mats = new LcMaterial[6]
            {
                new LcMaterial() { Color = new Color(0xff0000) },
                new LcMaterial() { Color = new Color(0x00ff00) },
                new LcMaterial() { Color = new Color(0x0000ff) },
                new LcMaterial() { Color = new Color(0xff0000) },
                new LcMaterial() { Color = new Color(0x00ff00) },
                new LcMaterial() { Color = new Color(0x0000ff) }
            };
            //var mats = new LcMaterial[1]
            //{
            //    new LcMaterial() { Color = new Color(0xffffff) },
            //    new LcMaterial() { Color = new Color(0x00ff00) },
            //    new LcMaterial() { Color = new Color(0x0000ff) },
            //    new LcMaterial() { Color = new Color(0xff0000) },
            //    new LcMaterial() { Color = new Color(0x00ff00) },
            //    new LcMaterial() { Color = new Color(0x0000ff) }
            //};
            Vector3 cenOffset = (end - start).MulScalar(0.5);
            double width = Math.Abs(end.X - start.X);
            double height = Math.Abs(end.Y - start.Y);
            this.cuboid = new LcCuboidInstance(width, height, depth, ComponentManager.GetCptDef<LcCuboidDef>("长方体", "长方体", CuboidAttribute.BuiltinUuid));

            //this.cuboid.Solid.Topoable = true;
            this.cuboid.Initilize(this.docRt.Document);

            (this.cuboid.Rt3DAction as IComponentAction).SetDocEditor(this.docEditor);
            //this.cuboid.Rt3DAction = this;
            this.cuboid.Position.AddVectors(start, cenOffset);
            //this.cuboid.UpdateMatrix();
            this.docRt.Document.ModelSpace.InsertElement(this.cuboid);
        }
    }
}
